package com.sky.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.context.BaseContext;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜品业务访问层
 *
 * @Author mr.zhang
 * Date 2025/5/20 22:04
 */
@Service
public class DishServiceImpl implements DishService {

    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorMapper dishFlavorMapper;


    /**
     * 新增菜品
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DishDTO dto) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dto,dish);
        dish.setCreateTime(LocalDateTime.now());
        dish.setUpdateTime(LocalDateTime.now());
        dish.setCreateUser(BaseContext.getCurrentId());
        dish.setUpdateUser(BaseContext.getCurrentId());
        dishMapper.add(dish);



        List<DishFlavor> dishFlavorList = null;
        List<DishFlavor> flavors = dto.getFlavors();
        if(flavors!=null && flavors.size()>0){
            dishFlavorList = flavors.stream().map(x->{
                DishFlavor dishFlavor = new DishFlavor();
                BeanUtils.copyProperties(x,dishFlavor);
                dishFlavor.setDishId(dish.getId());
                return dishFlavor;
            }).collect(Collectors.toList());
            for (DishFlavor dishFlavor : dishFlavorList) {
                dishFlavorMapper.add(dishFlavor);
            }
        }


        //清除缓存
        String key = "dish:" + dto.getCategoryId();
        redisTemplate.delete(key);

    }

    /**
     * 分页查询菜品数据
     *
     * @param dishPageQueryDTO
     * @return
     */
    @Override
    public PageResult listPage(DishPageQueryDTO dishPageQueryDTO) {
        //设置分页参数
        PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
        //调用mapper方法
        List<DishVO> dishList = dishMapper.listPage(dishPageQueryDTO);

        //使用page强转
        Page<DishVO> page = (Page<DishVO>) dishList;
        //返回数据
        return new PageResult(page.getTotal(),page.getResult());
    }


    /**
     * 删除菜品
     *
     * @param ids
     */
    @Override
    public void delete(List<Integer> ids) throws Exception {
        //判断ids是否为空
        if(ids.size()==0){
            throw new Exception("ids为空,不能删除");
        }
        //获取起售的菜品数量,大于1就提示不能删除
        int count = getByIdsAndStatus(ids, 1);
        if(count>0){
            throw new Exception("传入的ids中存在起售的菜品,不能删除");
        }
        //获取菜品是否关联套餐,关联就提示不能删除
        int countSetmeal = getCountSetmeal(ids);
        if (countSetmeal>0){
            throw new Exception("传入的ids中存在与套餐关联的菜品,不能删除");
        }
        //正常删除,但是口味也要删除
        dishMapper.delete(ids);

        dishFlavorMapper.batchDelete(ids);



        //清除缓存
        ids.stream().forEach(x->{
            Dish dish = dishMapper.getById(x);
            String key = "dish:" + dish.getCategoryId();
            redisTemplate.delete(key);
        });


    }


    /**
     * 根据id查询起售数据个数
     */
    public int getByIdsAndStatus(List<Integer> ids, Integer status){
        int count = dishMapper.getByIdsAndStatus(ids,status);
        return count;
    }

    /**
     * 根据菜品id查询套餐数量
     */
    public int getCountSetmeal(List<Integer> ids){
        int count = dishMapper.getCountSetmeal(ids);
        return count;
    }


    /**
     * 根据id查询菜品数据,查询回显
     *
     * @param id
     * @return
     */
    @Override
    public DishVO getById(Integer id) throws Exception {
        //创建值对象实例与实体类实例
        DishVO dishVO = new DishVO();
        Dish dish = new Dish();
        List<DishFlavor> dishFlavorList = new ArrayList<>();
        //调用mapper层方法并赋值给实体类实例
        dish = dishMapper.getById(id);
        if(dish==null){
            throw new Exception("没有id对应的菜品数据");
        }
        BeanUtils.copyProperties(dish,dishVO);
        dishFlavorList = dishFlavorMapper.getByDishId(id);
        dishVO.setFlavors(dishFlavorList);

        return dishVO;
    }


    /**
     * 修改菜品
     *
     * @param dishDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DishDTO dishDTO) {
        //修改菜品
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        dish.setUpdateTime(LocalDateTime.now());
        dish.setUpdateUser(BaseContext.getCurrentId());
        dishMapper.update(dish);

        //修改菜品口味
        List<DishFlavor> flavorList = dishDTO.getFlavors();
        DishFlavor dishFlavor = new DishFlavor();
        for (DishFlavor flavor : flavorList) {
            BeanUtils.copyProperties(flavor,dishFlavor);
            flavor.setDishId(dishDTO.getId());
            dishFlavorMapper.update(flavor);
        }

        //清除缓存
        String key = "dish:" + dishDTO.getCategoryId();
        redisTemplate.delete(key);
    }


    /**
     * 修改菜品状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(Long id, Integer status) {
        Dish dish = new Dish();
        dish.setStatus(status);
        dish.setId(id);
        dish.setUpdateTime(LocalDateTime.now());
        dish.setUpdateUser(BaseContext.getCurrentId());

        dishMapper.updateStatus(dish);


        //清除缓存
        String key = "dish:" + dish.getCategoryId();
        redisTemplate.delete(key);
    }


    /**
     * 根据分类查询菜品
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<DishVO> getByType(Long categoryId) {
        List<DishVO> dishVOList = dishMapper.getByType(categoryId);

        return dishVOList;
    }


    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 条件查询菜品和口味
     * @param dish
     * @return
     */
    public List<DishVO> listWithFlavor(Dish dish) {
        String key = "redis:" + dish.getCategoryId();
        //1.查询缓存中的菜品是否存在
        List<String> dishJSONList = redisTemplate.opsForList().range(key, 0, -1);
        if (CollUtil.isNotEmpty(dishJSONList)) {
            List<DishVO> dishVOList = new ArrayList<>();
            for (String jsonStr : dishJSONList) {
                List<DishVO> cachedList = JSON.parseArray(jsonStr, DishVO.class);//获取缓存中的数组中的列表
                dishVOList.addAll(cachedList);
            }
            return dishVOList;
        }


        //2.如果不存在,从数据库中查询
        List<Dish> dishList = dishMapper.list(dish);
        List<DishVO> dishVOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(dishList)){

            for (Dish d : dishList) {
                DishVO dishVO = new DishVO();
                BeanUtils.copyProperties(d,dishVO);

                //根据菜品id查询对应的口味
                List<DishFlavor> flavors = dishFlavorMapper.getByDishId(Integer.valueOf(Math.toIntExact(d.getId())));

                dishVO.setFlavors(flavors);
                dishVOList.add(dishVO);
            }
            //3.将数据载入到缓存中
            redisTemplate.opsForList().leftPush(key,JSON.toJSONString(dishVOList));//注意,使用JSON.toJSONString转为标准的json字符串
        }
        return dishVOList;
    }
}
